package com.hm.service.framework.crypto.ECB;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * AES对称加密
 * mode:ECB模式（只需要密钥，不需要偏移量）
 * 密钥(只能大小写字母+数字+长度最长32位)
 */
public class AES_ECB {

    private static final Logger logger = LoggerFactory.getLogger(AES_ECB.class);

    //定义加密算法
    private static final String Algorithm = "AES/ECB/PKCS5Padding";

    /**
     * AES-ECB加密
     *
     * @param content 待加密文本
     * @return 密文
     */
    public static String encrypt(String secretKey, String content) {
        try {
            //检查非空
            if (secretKey == null || secretKey.isEmpty()) {
                logger.error("secretKey为空");
                return "secretKey为空";
            }
            //检查长度
            if (secretKey.length() != 32) {
                logger.error("secretKey长度不等于32");
                return "secretKey长度不等于32";
            }
            //正则表达式标识匹配字符串中的非字母和非数字的的字符，如果字符中含有特殊字符，则会匹配成功
            Pattern pattern = Pattern.compile("[^A-Za-z0-9]");
            Matcher matcher = pattern.matcher(secretKey);
            if (matcher.find()) {
                //说明有特殊字符
                logger.error("secretKey含有特殊字符");
                return "secretKey含有特殊字符";
            }
            if (content == null || content.isEmpty()) {
                logger.error("加密内容为空");
                return "";
            }
            Cipher cipher = Cipher.getInstance(Algorithm);
            cipher.init(Cipher.ENCRYPT_MODE, generateKeySpec(secretKey));
            byte[] contentBytes = content.getBytes(StandardCharsets.UTF_8);
            byte[] cipherBytes = cipher.doFinal(contentBytes);
            return Base64.getEncoder().encodeToString(cipherBytes);
        } catch (Exception e) {
            String message = e.getMessage();
            logger.error(e.getMessage());
            return message;
        }
    }

    /**
     * AES-ECB解密
     *
     * @param content 密文
     * @return 解密后的内容
     */
    public static String decrypt(String secretKey, String content) {
        try {
            //检查非空
            if (secretKey == null || secretKey.isEmpty()) {
                logger.error("secretKey为空");
                return "secretKey为空";
            }
            //检查长度
            if (secretKey.length() != 32) {
                logger.error("secretKey长度不等于32");
                return "secretKey长度不等于32";
            }
            //正则表达式标识匹配字符串中的非字母和非数字的的字符，如果字符中含有特殊字符，则会匹配成功
            Pattern pattern = Pattern.compile("[^A-Za-z0-9]");
            Matcher matcher = pattern.matcher(secretKey);
            if (matcher.find()) {
                //说明有特殊字符
                logger.error("secretKey含有特殊字符");
                return "secretKey含有特殊字符";
            }
            if (content == null || content.isEmpty()) {
                logger.error("解密内容为空");
                return "";
            }
            //base64密文解码
            byte[] encrypted = Base64.getDecoder().decode(content);
            Cipher cipher = Cipher.getInstance(Algorithm);
            cipher.init(Cipher.DECRYPT_MODE, generateKeySpec(secretKey));
            byte[] decryptBytes = cipher.doFinal(encrypted);
            return new String(decryptBytes, StandardCharsets.UTF_8);
        } catch (Exception e) {
            String message = e.getMessage();
            logger.error(e.getMessage());
            return message;
        }
    }

    //注意如果secretKey是动态的，这里不能写单例模式 必须每次要new
    private static SecretKeySpec generateKeySpec(String secretKey) {
        return new SecretKeySpec(secretKey.getBytes(), "AES");
    }

}
